package com.ruoyi.contract.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.ice.common.model.IceShowConf;
import com.ice.core.Ice;
import com.ice.core.context.IcePack;
import com.ice.core.context.IceRoam;
import com.ice.core.utils.JacksonUtils;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.contract.domain.ConRule;
import com.ruoyi.contract.service.ConRuleService;
import com.ruoyi.contract.mapper.ConRuleMapper;
import com.ruoyi.ice.domain.IceResponse;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.*;

/**
* @author 姚煜峰
* @description 针对表【CON_RULE】的数据库操作Service实现
* @createDate 2023-06-28 15:33:15
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class ConRuleServiceImpl extends ServiceImpl<ConRuleMapper, ConRule>
    implements ConRuleService{

    @Value("${other.ice.url}")
    private String iceUrl;

    @Value("${ice.app}")
    private String iceApp;

    final String iceBaseUrl = "/ice-server/base/edit";

    final String confDetail = "/ice-server/conf/detail";

    @Override

    public AjaxResult insert(ConRule conRule) throws Exception {

        if(StringUtils.isNull(conRule.getConId())){
            throw new Exception("合同ID不能为空");
        }

        if(StringUtils.isEmpty(conRule.getProjectType())){
            throw new Exception("项目类型不能为空");
        }

        if(StringUtils.isNull(conRule.getProjectId())){
            throw new Exception("服务名称不能为空");
        }

        if(StringUtils.isEmpty(conRule.getCurrency())){
            throw new Exception("币种不能为空");
        }

        if(StringUtils.isNull(conRule.getDecimalNum())){
            conRule.setDecimalNum(new BigDecimal("2"));
        }

        if(StringUtils.isEmpty(conRule.getDecimalMethod())){
            conRule.setDecimalMethod("0");
        }

        if("Y".equals(conRule.getIsAuto())){

            //校验 合同 项目类型 服务名名称 币种 自动计费规则是否存在

            QueryWrapper<ConRule> queryWrapper = new QueryWrapper<>();

            queryWrapper.lambda()
                    .eq(ConRule::getConId,conRule.getConId())
                    .eq(ConRule::getProjectType,conRule.getProjectType())
                    .eq(ConRule::getProjectId,conRule.getProjectId())
                    .eq(ConRule::getCurrency,conRule.getCurrency())
                    .eq(ConRule::getIsAuto,"Y");

            ConRule check = this.getOne(queryWrapper);

            if(StringUtils.isNotNull(check)){
                throw new Exception("自动计费规则已存在");
            }else {
                conRule.setIceId(Long.valueOf(newIceBaseId(conRule).toString()));
            }

        }else {

            if (StringUtils.isNull(conRule.getUnitPrice())) {
                throw new Exception("非自动计费,单价不能为空");
            }

        }

        return this.save(conRule) ? AjaxResult.success() : AjaxResult.error();
    }

    @Override

    public AjaxResult updateRules(ConRule conRule) throws Exception {

        if(StringUtils.isNull(conRule.getConId())){
            throw new Exception("合同ID不能为空");
        }

        if(StringUtils.isEmpty(conRule.getProjectType())){
            throw new Exception("项目类型不能为空");
        }

        if(StringUtils.isNull(conRule.getProjectId())){
            throw new Exception("服务名称不能为空");
        }

        if(StringUtils.isEmpty(conRule.getCurrency())){
            throw new Exception("币种不能为空");
        }

        if("Y".equals(conRule.getIsAuto())) {

            conRule.setUnitPrice(null);

            //校验 合同 项目类型 服务名名称 币种 自动计费规则是否存在

            QueryWrapper<ConRule> queryWrapper = new QueryWrapper<>();

            queryWrapper.lambda()
                    .eq(ConRule::getConId, conRule.getConId())
                    .eq(ConRule::getProjectType, conRule.getProjectType())
                    .eq(ConRule::getProjectId, conRule.getProjectId())
                    .eq(ConRule::getCurrency, conRule.getCurrency())
                    .eq(ConRule::getIsAuto, "Y")
                    .ne(ConRule::getRuleId,conRule.getRuleId());

            ConRule check = this.getOne(queryWrapper);

            if (StringUtils.isNotNull(check)) {
                throw new Exception("自动计费规则已存在");
            }else{

                ConRule oldRule = this.getById(conRule.getRuleId());

                if(StringUtils.isNotNull(oldRule.getIceId())){
                    conRule.setIceId(oldRule.getIceId());
                }else {
                    conRule.setIceId(Long.valueOf(newIceBaseId(conRule).toString()));
                }


            }

        }else {

            if(StringUtils.isNull(conRule.getUnitPrice())){
                throw new Exception("非自动计费,单价不能为空");
            }

            //conRule.setIceId(null);
        }

        return this.updateById(conRule) ? AjaxResult.success() : AjaxResult.error();
    }

    @Override
    public AjaxResult removeIds(Long[] ids) throws Exception {

        List<ConRule> rules = this.listByIds(Arrays.asList(ids));

        for(ConRule rule:rules){

            if(StringUtils.isNotNull(rule.getIceId())){

                removeIceBase(rule.getIceId());

            }

            this.removeById(rule.getRuleId());

        }

        return AjaxResult.success();
    }

    public void removeIceBase(Long iceId) throws Exception {

        RestTemplate restTemplate = new RestTemplate();

        Map<String,Object> map = new HashMap<>();

        map.put("app",iceApp);
        map.put("status",0);
        map.put("id",iceId);

        String url = iceUrl + iceBaseUrl;

        //System.out.println(url);
        //
        //System.out.println(map);

        HttpHeaders headers = new HttpHeaders();

        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity<Map<String,Object>> request = new HttpEntity<>(map,headers);

        IceResponse iceResponse = restTemplate.postForObject(url,request,IceResponse.class);

        if(StringUtils.isNull(iceResponse)){
            throw new Exception("ice服务异常");
        }

    }

    public Object newIceBaseId(ConRule rule) throws Exception {
        RestTemplate restTemplate = new RestTemplate();

        Map<String,Object> map = new HashMap<>();

        map.put("app",iceApp);
        map.put("debug","0");
        map.put("name",rule.getConId() + "_" + rule.getProjectType() + "_" + rule.getProjectId() + "_" + rule.getCurrency());
        map.put("type",1);

        String url = iceUrl + iceBaseUrl;

        //System.out.println(url);
        //
        //System.out.println(map);

        HttpHeaders headers = new HttpHeaders();

        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity<Map<String,Object>> request = new HttpEntity<>(map,headers);



        IceResponse iceResponse = restTemplate.postForObject(url,request,IceResponse.class);

        if(StringUtils.isNull(iceResponse)){
            throw new Exception("ice服务异常");
        }

        return iceResponse.getData();

    }

    @Override
    public List<IceRoam> autoCal(Long conId, String projectType, Map<String, Object> map){

        List<ConRule> rules = this.list(new QueryWrapper<ConRule>().lambda()
                .eq(ConRule::getConId,conId)
                .eq(ConRule::getProjectType,projectType)
                .eq(ConRule::getIsAuto,"Y"));

        List<IceRoam> iceRoams = new ArrayList<>();

        if(rules.size()>0){

            for(ConRule rule:rules){

                if(StringUtils.isNotNull(rule.getIceId())){

                    IcePack pack = new IcePack();
                    pack.setIceId(rule.getIceId());
                    IceRoam roam = new IceRoam();

                    //遍历 map 生成 roam
                    for(String key:map.keySet()){

                        roam.put(key,String.valueOf(map.get(key)));

                    }

                    System.out.println(roam);

                    pack.setRoam(roam);

                    Ice.syncProcess(pack);

                    System.out.println(roam);

                    String result = String.valueOf(roam.get("result"));
                    //
                    //System.out.println("result:" + result);

                    if(StringUtils.isNotEmpty(result)&&!"null".equals(result)){

                        BigDecimal price = new BigDecimal(result);

                        Integer decimalNum = rule.getDecimalNum().intValue();

                        String decimalMethod = rule.getDecimalMethod();

                        if("0".equals(decimalMethod)){
                            price = price.setScale(decimalNum,BigDecimal.ROUND_HALF_UP);
                        }else if ("1".equals(decimalMethod)){
                            //向上取整
                            price = price.setScale(decimalNum,BigDecimal.ROUND_UP);
                        }else if ("2".equals(decimalMethod)){
                            //向下取整
                            price = price.setScale(decimalNum,BigDecimal.ROUND_DOWN);
                        }

                        roam.put("finalResult",price);

                        roam.put("ruleId",rule.getRuleId());

                        iceRoams.add(roam);
                    }
                    
                }

            }

        }

        return iceRoams;
    }

    @Override
    public List<ConRule> selectConRuleByProjectId(Long projectId) {
        return baseMapper.selectConRuleByProjectId(projectId);
    }

    @Override
    public IceShowConf getIceConfig (Long id) {
        ConRule conRule = getById(id);

        if(StringUtils.isNotNull(conRule)&&StringUtils.isNotNull(conRule.getIceId())){

            RestTemplate restTemplate = new RestTemplate();

            String url = iceUrl + confDetail + "?app=" + iceApp + "&iceId=" + conRule.getIceId();

            String str = restTemplate.getForObject(url,String.class);

            //System.out.println(str);

            Gson gson = new Gson();

            IceResponse<IceShowConf> response = gson.fromJson(str,new TypeToken<IceResponse<IceShowConf>>(){}.getType());

            return response.getData();

        }

        return null;

    }

    @Override
    public Long getDiscRuleByConId(Long conId) {
        return baseMapper.getDiscRuleByConId(conId)!=null?baseMapper.getDiscRuleByConId(conId):-1;
    }

}




